package be.kuleuven.cs.mop.domain.model.impl;


import static org.junit.Assert.*;

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import be.kuleuven.cs.mop.TestEnvironment;
import be.kuleuven.cs.mop.domain.exceptions.TaskManagerException;



public class UserImplTest {
	
	private static TestEnvironment ENV;
	
	private static String	testName	= "Test User Name";
	private static UserImpl testUser1;
	private static UserImpl testUser2;
	
	
	
	@Before
	public void setUp() throws Exception {
		ENV = TestEnvironment.newInstance();
		
		testUser1 = new UserImpl(ENV.world, testName, ENV.userTypes.get(1));
	}
	
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {}
	
	@After
	public void tearDown() throws Exception {}
	
	@AfterClass
	public static void tearDownAfterClass() throws Exception {}
	
	@Test
	public void testConstructorLegalCase() throws TaskManagerException {
		testUser2 = new UserImpl(ENV.world, "user", ENV.userTypes.get(1));
		assertEquals(testUser2.getWorld(),	ENV.world);
		assertEquals(testUser2.getName(),	"user");
		assertTrue(testUser2.getTasks().isEmpty());
		assertTrue(testUser2.getTasksUnfinished().isEmpty());
	}
	
	@Test(expected=TaskManagerException.class)
	public void testConstructorIllegalCase1() throws TaskManagerException {
		new UserImpl(ENV.world, null, null);
	}
	
	@Test(expected=TaskManagerException.class)
	public void testConstructorIllegalCase2() throws TaskManagerException {
		new UserImpl(ENV.world, "", null);
	}
	
	@Test(expected=TaskManagerException.class)
	public void testConstructorIllegalCase3() throws TaskManagerException {
		new UserImpl(ENV.world, "identical", ENV.userTypes.get(1));
		new UserImpl(ENV.world, "identical", ENV.userTypes.get(1));
	}
	
	@Test
	public void testCreateTaskLegalCase() throws TaskManagerException {
		final TaskImpl task =
			testUser1.createTask(
					new Schedule(ENV.datum1, ENV.datum2, 300000L),
					new HashSet<TaskImpl>(),
					new HashMap<String, Field>(),
					ENV.testTaskType);
		
		assertEquals(testUser1 ,	task.getUser());
		assertTrue(testUser1.getTasks().contains(task));
	}
	
	@Test(expected=TaskManagerException.class)
	public void testCreateTaskIllegalCase1() throws TaskManagerException{
		testUser1.createTask(null, null, null, null);
	}
	
	@Test(expected=TaskManagerException.class)
	public void testCreateTaskIllegalCase2() throws TaskManagerException {
		testUser1.createTask(
				new Schedule(ENV.datum1, ENV.datum2, 300000L),
				null, null, null);
	}
	
	@Test(expected=TaskManagerException.class)
	public void testCreateTaskIllegalCase3() throws TaskManagerException {
		testUser1.createTask(
				new Schedule(ENV.datum1, ENV.datum2, 300000L),
				new HashSet<TaskImpl>(),
				null, null);
	}
	
	@Test(expected=TaskManagerException.class)
	public void testCreateTaskIllegalCase4() throws TaskManagerException {
		testUser1.createTask(
				new Schedule(ENV.datum1, ENV.datum2, 300000L),
				new HashSet<TaskImpl>(),
				new HashMap<String, Field>(),
				null);
	}
	
	@Test
	public void testFocusDeadline() {
		final Calendar fdl = ENV.user1.getFocusDeadline();
		assertNotNull(fdl);
		final Calendar now = new GregorianCalendar();
		now.setTimeInMillis(System.currentTimeMillis());
		assertTrue(fdl.after(now));
	}
	
	@Test
	public void testRemoveTaskLegalCase() throws TaskManagerException {
		final TaskImpl task = testUser1.createTask(
				new Schedule(ENV.datum1, ENV.datum2, 300000L),
				new HashSet<TaskImpl>(),
				new HashMap<String, Field>(),
				ENV.testTaskType);
		
		assertTrue(testUser1.getTasks().contains(task));
		testUser1.remove(task);
		assertFalse(testUser1.getTasks().contains(task));
	}
	
	public void testValidation() {
		assertNotNull(ENV.user1.toString());
		assertFalse(ENV.user1.toString().isEmpty());
		assertFalse(ENV.user1.equals(ENV.user2));
//		assertFalse(UserImpl.isValidName(null));
//		assertFalse(UserImpl.isValidName(""));
	}
	
}